package com.blackcat.rabbitmq.config;

import com.alibaba.fastjson.JSONObject;
import com.blackcat.rabbitmq.entity.Simple;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.Charset;

/**
 * 描述 ：消费者
 *  /@RabbitListener 注解提供了@QueueBinding、@Queue、@Exchange 等对象，通过这个组合注解配置交换机、绑定路由并且配置监听功能等。
 *      Exchange:消息队列交换机，按一定的规则将消息路由转发到某个队列，对消息进行过虑。
 *      Queue:消息队列，存储消息的队列，消息到达队列并转发给指定的消费方。
 *  /@RabbitHandler 注解为具体接收的方法。
 * @author : zhangdahui
 * @date : 2022/8/15 10:34
 */
@Slf4j
@Component
public class Consumer {

    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("dh-basedata-refDataSync"))
    public void refCodeTest(String msg) {
//    public void refCodeTest(MqPushMainDto msg) {
        System.out.println("参考：" + msg);
    }

    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("qqqqq"))
    public void send(String msg, Channel channel, Message message) throws IOException {
        System.out.println("msg "+msg);
        System.out.println("message "+message);
//        System.out.println("message "+message.getBodyContentAsString());

        System.out.println(new String(message.getBody(), Charset.defaultCharset().name()));
    }

    /**
     * 描述 : 消费者通过 @RabbitListener 注解创建侦听器端点，绑定 notice_queue 队列。
     * @author : zhangdahui
     * @date : 2022/8/15 10:36
    */
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("notice_queue"))
    public void process(String message) {
        System.out.println("消费者收到通知：" + message);
    }

    /**
     * 描述 : 消费者通过 @RabbitListener 注解创建侦听器端点，绑定 notice_user_queue 队列。
     * @author : zhangdahui
     * @date : 2022/8/15 10:36
     */
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("notice_user_queue"))
    public void simple(Simple simple) {
        System.out.println("收到用户创建信息为：" + simple);
    }

    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("work_queue"))
    public void work1(String message){
        System.out.println("工作队列模式 消费者1收到的消息是 "+message);
    }

    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("work_queue"))
    public void work2(String message){
        System.out.println("工作队列模式 消费者2收到的消息是 "+message);
    }

    // 消费者A
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("sms-fanout-queue"))
    public void receiverQueueA(String msg, Channel channel, Message message) throws IOException  {
        log.info("消费者sms --接收到消息：{}", msg);
        // 下列是手动签收
        /*try {
            log.info("消费者sms --接收到消息：{}", msg);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            if (message.getMessageProperties().getRedelivered()) {
                log.error("消息已重复处理失败,拒绝再次接收...");
                //basicReject: 拒绝消息，与basicNack区别在于不能进行批量操作，其他用法很相似 false表示消息不再重新进入队列
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false); // 拒绝消息
            } else {
                log.error("消息即将再次返回队列处理...");
                // basicNack:表示失败确认，一般在消费消息业务异常时用到此方法，可以将消息重新投递入队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }
        }*/
    }

    // 消费者B
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("email-fanout-queue"))
    public void receiverQueueB(String msg, Channel channel, Message message) throws IOException  {
        log.info("消费者email --接收到消息：{}", msg);
        /*try {
            log.info("消费者email --接收到消息：{}", msg);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            if (message.getMessageProperties().getRedelivered()) {
                log.error("消息已重复处理失败,拒绝再次接收...");
                //basicReject: 拒绝消息，与basicNack区别在于不能进行批量操作，其他用法很相似 false表示消息不再重新进入队列
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false); // 拒绝消息
            } else {
                log.error("消息即将再次返回队列处理...");
                // basicNack:表示失败确认，一般在消费消息业务异常时用到此方法，可以将消息重新投递入队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }
        }*/
    }

    // 消费者C
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("wechat-fanout-queue"))
    public void receiverQueueC(String msg, Channel channel, Message message) throws IOException {
        log.info("消费者wechat --接收到消息：{}", msg);
        /*try {
            log.info("消费者wechat --接收到消息：{}", msg);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            if (message.getMessageProperties().getRedelivered()) {
                log.error("消息已重复处理失败,拒绝再次接收...");
                //basicReject: 拒绝消息，与basicNack区别在于不能进行批量操作，其他用法很相似 false表示消息不再重新进入队列
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false); // 拒绝消息
            } else {
                log.error("消息即将再次返回队列处理...");
                // basicNack:表示失败确认，一般在消费消息业务异常时用到此方法，可以将消息重新投递入队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }
        }*/
    }

    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("yyds1"))
    public void receiver(String data){
        System.out.println("一号消息队列监听器 "+data);
    }

    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("yyds2"))
    public void receiver2(String data){
        System.out.println("二号消息队列监听器 "+data);
    }


    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("delay.queue"))
    public void delay1(String data){
        System.out.println("delay.queue消息队列监听器 "+data);
    }
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("queue.direct.1"))
    public void queue(String data){
        System.out.println("queue.direct.1消息队列监听器 "+data);
    }

}
